#include "ActionManager.h"
#include "..\utils\Log.h"
#include "..\utils\StringUtils.h"

namespace ds {

ActionManager::ActionManager() {
	m_Actions.assureSize(32);
	m_ActiveActions.assureSize(32);
}


ActionManager::~ActionManager() {	
	m_Actions.deleteContents();	
}

void ActionManager::addAction(Action* action) {
	LOGC(logINFO,"ActionManager") << "adding new action " << action->getName();
	m_Actions.append(action);
}

void ActionManager::startAction(const char* name) {	
	Action* act = findAction(name);
	if ( act != 0 ) {
		LOGC(logINFO,"ActionManager") << "starting action " << name;
		act->start();
		m_ActiveActions.append(act);
	}
	else {
		LOGC(logERROR,"ActionManager") << "cannot find action " << name;
	}
}

void ActionManager::stopAction(const char* name) {
	Action* act = findActiveAction(name);
	if ( act != 0 ) {
		LOGC(logINFO,"ActionManager") << "stopping action " << name;
		act->stop();
		act->setActive(false);
	}
	else {
		LOGC(logERROR,"ActionManager") << "cannot find active action " << name;
	}
}

void ActionManager::update(float elapsed) {
	uint32 cnt = 0;
	while ( cnt < m_ActiveActions.num() ) {
		Action* action = m_ActiveActions[cnt];
		if ( action->isActive() ) {
			action->update(elapsed);
		}
		if ( !action->isActive() ) {
			LOGC(logINFO,"ActionManager") << "action " << action->getName() << " has finished - removing from active actions";
			m_ActiveActions.removeIndex(cnt);
		}
		else {
			++cnt;
		}
	}
}

bool ActionManager::isActive(const char* name) {
	LOGC(logINFO,"ActionManager") << "looking for active action " << name;
	IdString hash = string::murmur_hash(name,strlen(name),0);
	for ( uint32 i = 0 ; i < m_ActiveActions.num(); ++i ) {
		if ( m_ActiveActions[i]->getHash() == hash) {
			LOGC(logINFO,"ActionManager") << "found action";
			return true;
		}
	}
	return false;
}

Action* ActionManager::findActiveAction(const char* name) {
	LOGC(logINFO,"ActionManager") << "looking for active action " << name;
	LOGC(logINFO,"ActionManager") << "currently active actions " << m_ActiveActions.num();
	IdString hash = string::murmur_hash(name,strlen(name),0);
	for ( uint32 i = 0 ; i < m_ActiveActions.num(); ++i ) {
		if ( m_ActiveActions[i]->getHash() == hash) {
			LOGC(logINFO,"ActionManager") << "found action";
			return m_ActiveActions[i];
		}
	}
	return 0;
}

Action* ActionManager::findAction(const char* name) {
	LOGC(logINFO,"ActionManager") << "looking for action " << name;
	IdString hash = string::murmur_hash(name,strlen(name),0);
	for ( uint32 i = 0 ; i < m_Actions.num(); ++i ) {
		if ( m_Actions[i]->getHash() == hash ) {
			LOGC(logINFO,"ActionManager") << "found action";
			return m_Actions[i];
		}
	}
	return 0;
}

void ActionManager::debug() {	
	LOGC(logINFO,"ActionManager") << "- Registered actions";
	for ( size_t i = 0 ; i < m_Actions.num(); ++i ) {
		LOGC(logINFO,"ActionManager") << m_Actions[i]->getName();
	}
	LOGC(logINFO,"ActionManager") << "- Active actions";
	for ( size_t i = 0 ; i < m_ActiveActions.num(); ++i ) {
		LOGC(logINFO,"ActionManager") << m_ActiveActions[i]->getName();
	}
}

}
